import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/Login.vue'
import AppLayout from '@/components/AppLayout.vue'
import Empty from '@/components/empty.vue'
import { GetNavigationMenus } from '@/api/index'

Vue.use(Router)

// 1. 定义基础路由（不需要权限的页面）
export const constantRoutes = [
  {
    path: '/',
    redirect: '/login'
  },
  {
    path: '/login',
    name: 'Login',
    component: Login
  },
  {
    path: '/AppLayout',
    name: 'AppLayout', // 为AppLayout路由设置name，便于后续查找
    component: AppLayout,
    meta: {
      title: '演示'
    },
    children: [] // 初始子路由为空，等待动态添加
  },
  // 404页面路由应最后定义，确保它能捕获所有未匹配的路由
  {
    path: '*',
    component: Empty // 请确保创建了这个组件
  }
]

// 创建 router 实例
const router = new Router({
  base: process.env.NODE_ENV === 'production' ? '/dist/' : '/',
  mode: 'history',
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes
})

// 2. 防止连续点击多次路由报错
const routerPush = Router.prototype.push
const routerReplace = Router.prototype.replace

Router.prototype.push = function push(location) {
  return routerPush.call(this, location).catch(err => err)
}

Router.prototype.replace = function push(location) {
  return routerReplace.call(this, location).catch(err => err)
}

// 3. 定义一个状态标志，防止重复添加动态路由
let isDynamicRoutesAdded = false

// 4. 动态添加路由的核心函数
export function addDynamicRoutes(menuData) {
  if (!menuData || !menuData.Result) {
    console.error('菜单数据格式错误')
    return
  }

  // 处理菜单数据，生成路由配置
  const newRoutes = processMenuData(menuData)
  
  if (newRoutes.length === 0) {
    console.warn('未生成任何路由')
    return
  }

  // 使用 Vue Router 3 的 addRoutes 方法动态添加路由
  // 注意：addRoutes 会将新路由添加到路由列表的末尾，因此404路由可能会被覆盖
  // 解决方法：在添加动态路由后，再次添加404路由以确保其始终在最后
  router.addRoutes([
    {
      path: '/AppLayout',
      name: 'AppLayout',
      component: AppLayout,
      children: newRoutes // 添加处理后的动态路由作为子路由
    },
    // 重新添加404路由以确保其匹配优先级最低
    {
      path: '*',
      component:Empty

    }
  ])

  isDynamicRoutesAdded = true // 设置标志位

  console.log('✅ 动态路由添加完成', newRoutes)
}

// 5. 处理菜单数据，生成路由配置数组
function processMenuData(menuData) {
  const routes = []

  // 合并TopMenus和LeftMenus进行处理
  const allMenus = [...(menuData.Result.TopMenus || []), ...(menuData.Result.LeftMenus || [])]

  // 递归处理菜单项
  const processItems = (items) => {
    items.forEach(item => {
      if (item.items && item.items.length > 0) {
        processItems(item.items) // 递归处理子项
      } else {
        if (item.NavigationUrl) {
          routes.push({
            path: item.NavigationUrl,
            name: item.Name || `route_${item.Id}`, // 为每个路由设置唯一的name
            component: getComponent(item.NavigationUrl),
            meta: { 
              title: item.Name,
              isDynamic: true // 标记为动态路由，便于管理
            }
          })
        }
      }
    })
  }

  processItems(allMenus)
  return routes
}

// 6. 根据路径获取组件
function getComponent(componentName) {
  if (!componentName) {
    console.warn('NavigationUrl为空，使用默认空组件')
    return Empty
  }

  // 如果直接是组件对象，直接返回
  if (typeof componentName === 'function' || typeof componentName === 'object') {
    return componentName
  }

  // 处理组件路径，确保格式正确
  let componentPath = componentName
  if (componentPath.startsWith('/')) {
    componentPath = componentPath.substring(1)
  }
  if (componentPath.endsWith('.vue')) {
    componentPath = componentPath.replace('.vue', '')
  }

  // 尝试动态导入
  return () => import(`@/views/${componentPath}.vue`).catch(() => {
    console.warn(`动态导入组件失败: ${componentPath}，使用空组件`)
    return Empty
  })
}

// 7. 初始化动态路由的异步函数
export async function initDynamicRoutes() {
  try {
    // 如果没有保存的数据，则从API获取
    const response = await GetNavigationMenus()
    addDynamicRoutes(response)
    return true
  } catch (error) {
    console.error('初始化动态路由失败:', error)
    return false
  }
}

// 8. 路由守卫 - 控制动态路由的加载时机
router.beforeEach(async (to, from, next) => {
  // 登录页面直接放行
  if (to.path === '/login') {
    next()
    return
  }

  // 如果动态路由还没有加载，先加载动态路由
  if (!isDynamicRoutesAdded) {
    try {
      const success = await initDynamicRoutes()
      if (success) {
        // 重新导航到当前路由，确保动态路由生效
        next({ ...to, replace: true })
      } else {
        console.error('加载动态路由失败，跳转到登录页')
        next('/login')
      }
    } catch (error) {
      console.error('路由守卫中加载动态路由失败:', error)
      next('/login')
    }
  } else {
    next()
  }
})

export default router